



function createSearchActionSlots({after = ''} = {}) {
    return `<z-space  class="z-table__search-actions" column-gap="3px" >
  <el-button class="z-table__search-action" type="primary" @click="zform__callEvent('form-submit', scope, $event)"">搜索</el-button>
  <el-button class="z-table__search-action"  @click="zform__reset(scope, $event)"">重置</el-button>
  ${after}
</z-space>`
}

function deepSet(obj, path, val) {
    let descendant = ZY.lodash.get(obj, path);
    if (!descendant) {
        descendant = val;
        ZY.lodash.set(obj, path, descendant);
    }
}

/**
 * 对接标准的url接口
 * @param defaultUrl
 * @param request
 * @param sPageInfo
 * @param listMethod
 * @param listReq
 * @param useAction
 * @param limit
 * @param onListSuccess
 * @param columnDefMap {{}}
 * @param appendColumns {[]}
 * @param columns {Array<>}
 * @param search {fields: {}, slots: {}}
 * @returns {{load: load, state, handlePageChange: handlePageChange}}
 */
export function useDataTable({defaultUrl = '', useAction= false, listReq, listMethod = 'get', onListSuccess, sPageInfo = {}, limit = null, appendColumns = [], columnDefMap = {},  request = {}, columns = [], search = {},infinite = false } = {}) {

    const { reactive } = window.vueCompositionAPI
    let pageInfo = {
        limit: 10 ,
        page: 1,
        ...sPageInfo
    }

    // console.log(limit)
    if (typeof limit !== 'undefined' && limit !== null) {
        pageInfo.limit = limit
    }

    let state = reactive({
        loading: false,
        result: {
            records: [],
            columns: [],
            current: 0,
            size: 0,
            total: 0
        },
        columns: []
    })

    let quickedMap = new Map();

    // 简单化action
    if (useAction) {
        appendColumns.push(
          {
              width: 180,
              label: '操作',
              actions: [
                  {
                      id: 'row-action',
                      useSlot: true
                  }
              ]
          }
        )
    }


    function resolveSearchFromColumns(columns, columnMap = {}) {
        if (!search.def) {
            search.def = {}
        }

        if (!search.def.properties) {
            search.def.properties = {}
        }

        if (Array.isArray(columns)) {
            columns.forEach(column => {
                // console.log(column)
                let o;
                if (column && column.search) {
                    o = column.search
                }
                if (columnMap[column.prop]) {
                    o = columnMap[column.prop]
                }
                if (column && column.quick) {
                    // quickedMap[]
                    // console.log(column, columns)
                    quickedMap.set(column.prop, column)
                }
                if (Array.isArray(column) && column[2]) {
                    o = column[2].search
                }
                // console.log(column)
                if (o) {
                    if (!o.ui) {
                        o.ui = {}
                    }
                    if (!o?.ui?.label) {
                        o.ui.label = column.label
                    }
                    search.def.properties[column.prop] = o
                }
            })
            ZY.lodash.each(columnDefMap, function (columnDef, key) {
                // console.log(columnDef, key)
                if (!search.def.properties[key]) {
                    search.def.properties[key] = columnDef?.search
                }
            })
            ZY.lodash.each(columnMap, function (columnDef, key) {
                // console.log(columnDef, key)
                if (!search.def.properties[key]) {
                    search.def.properties[key] = columnDef
                }
                if (columnDef.quick) {
                    quickedMap.set(key, columnDef)
                }
            })

            // console.log(columns)
            columns.push( {
                label: '',
                prop: 'TABLE_ROW_CHECK',
                width: '1px',
                useSlot: true
            })
        }
    }

    // function resolveRes(res) {
    //   console.log(res)
    //   load(res.result)
    // }

    /**
     * 处理
     * @param columns
     * @returns {unknown[]}
     */
    function private__resolveColumns(columns = []) {
        if (!Array.isArray(columns)) {
            ZCONSOLE.warn('columns 不是array')
            columns = []
        }
        let arr = columns.map(column => {
            let ret  = {}
            if (Array.isArray(column)) {
                if (column.length < 2) {
                    ret = {
                        label: column[0],
                        prop: column[0],
                    }
                }
                if (column.length > 1) {
                    ret = {
                        label: column[0],
                        prop: column[1],
                        ...column[2]
                    }
                }
            }
            if (column && column.hasOwnProperty('label') && column.hasOwnProperty('prop')) {
                ret = {
                    ...column
                }
            }
            // console.log(columnDefMap, ret)
            if (columnDefMap[ret.prop]) {
                ret = {
                    ...ret,
                    ...columnDefMap[ret.prop]
                }
            }

            return ret
        })

        // let keys = Object.keys(columns ?? {}) ?? []
        // let columnDefMapKeys = Object.keys(columnDefMap ?? {}) ?? []
        //
        // columnDefMapKeys.forEach(columnDefMapKey => {
        //   if (!keys.includes(columnDefMapKey)) {
        //
        //   }
        // })

        if (appendColumns) {
            arr = arr.concat(appendColumns)
        }

        return arr
    }

    /**
     * 加载静态数据
     * @param result
     */
    function load(result) {
        // console.log('datatable load', result)
        let {records = [], ...rest} = result
        state.result = {
            ...state.result,
            ...rest
        };
        // state.result.records = state.result.records.concat(records)
        // console.log(infinite)


        // if (rest.columnMap) {
        //   Object.entries(rest.columnMap).forEach(([key, column]) => {
        //     if (column.quick) {
        //       quickedMap.set(key, column)
        //     }
        //   })
        // }
        if (infinite) {
            state.result.records = state.result.records.concat(records)
        } else {
            state.result.records = [].concat(records)
        }
        if (state.columns.length < 1) {
            state.columns = private__resolveColumns(result.columns)
        }
        resolveSearchFromColumns(state.columns, rest.columnMap)
    }

    /**
     * 请求数据
     * @param options
     * @returns {Promise<void>}
     */
    async function req(options = {}) {
        state.loading = true;
        if (!options.params) {
            options.params = {
            }
        }
        options.params = Object.assign({
            ...pageInfo
        }, options.params)
        if (!options.method) {
            options.method = listMethod
        }
        // console.log('req', options.params)
        options.url = defaultUrl
        // console.log(request)
        let ret = []
        if (listReq) {
            ret = await ZY.awaitTo( listReq(options));
        } else {

            ret = await ZY.awaitTo( request(options));
        }
        let [err, res]  = ret


        // console.log(res)
        // console.log(state.loading)
        await ZY.sleep(30);

        if (onListSuccess) {
            onListSuccess(res)
        }

        state.loading = false;
        if (err) {
            return Promise.reject(err)
        } else {
            load(res.result)
        }
    }

    async function paginate(page, pageSize, options) {
        if (page) {
            pageInfo.page = page
        }
        if (pageSize) {
            pageInfo.limit = pageSize
        }
        await req(options)
    }


    async function handlePageChange({currentPage, pageSize} = {}, options) {
        console.log('handlePageChange', currentPage, pageSize, options)
        await paginate(currentPage, pageSize, options)
    }

    // columns映射到search上

    resolveSearchFromColumns(columns)

    function canRequest() {
        return request
    }

    function getRecords() {
        let ret = ZY.lodash.get(state, 'result.records', [])
        return ret
    }

    // 默认支持提交和重置
    deepSet(search, 'slots.object_beforeend', createSearchActionSlots())

    // console.log(search)

    if (columnDefMap) {
        Object.entries(columnDefMap).forEach(([key, column]) => {
            if (column.quick) {
                quickedMap.set(key, column)
            }
        })
    }


    return {
        state,
        req,
        getRecords,
        search,
        quickedMap,
        canRequest,
        handlePageChange,
        columns,
        load,
    }
}


export async function SimpleAutoSelectChange([type, args, ctx, obj] = [], def = [], {Request = window.Req} = {}) {
    if (type === 'com:select:change') {
        const DEFAULT_CALL_METHOD  = 'reloadOptionsAndSelectFirst'
        // console.log(obj)
        // let scope = args.scope
        let curFormCon = args?.scope?.curFormCon
        // console.log(args, curFormCon, obj)

        let model = {};
        if (curFormCon) {
            model  = curFormCon.exportCtx.getDataSync()
        }

        def.forEach(async (defItem) => {

            let {from, use, to = []} = defItem
            // console.log(from, use, to)
            if (from && use && to) {
                if (obj.self_path === from.self_path) {

                    let result = {}
                    // 如果有多个options情况
                    if (use.optionsUrl) {
                        let [err, res] = await ZY.awaitTo(
                            Request.get(use.optionsUrl)
                        )
                        // console.log(res)
                        result = res?.result ?? {}
                    }

                    if (use.ajaxOption) {

                        let res = await use.ajaxOption( model, args, obj)
                        result = res?.result ?? {}
                    }

                    to.forEach(item => {
                        if (Array.isArray(item)) {
                            let widgetContext = obj.getWidgetContext(item[0])
                            let useProp = item[1]
                            let useOption = item[2] ?? DEFAULT_CALL_METHOD
                            if (widgetContext) {
                                if (useProp) {
                                    if (Array.isArray(result[useProp])) {
                                        // console.log(widgetContext.setStaticOptions)
                                        widgetContext[useOption](result[useProp])
                                    }
                                }
                                // else if (useOption) {
                                //     if (typeof useOption === 'string') {
                                //         widgetContext[useOption]()
                                //     }
                                // }
                            }
                        }
                    })
                }
            }
        })


    }
}



export function layoutGridFormProperties(obj = {}, {from, to, config = []} = {}) {
    ZY.lodash.each(obj, function (item, key) {
        if (key === from) {
            ZY.T.deepInit(item, 'ui.wrap_start_tags', [])
            item.ui.wrap_start_tags.push(
              [
                  'zw-row',
                  config
              ]
            )
        }
        if (key === to) {
            ZY.T.deepInit(item, 'ui.wrap_end_tags', []);
            item.ui.wrap_end_tags.push(
              'zw-row'
            )
        }
    })
    return obj
}

/**
 *
 * @type {{zwRow: (function(*=, {from: *, to: *, config?: *}=): {})}}
 */
export let layoutGridFormPropertiesUtils = {
    zwRow: layoutGridFormProperties
}

export function batchlayoutGridFormProperties(obj, tasks=[]) {
    let ret = obj;
    tasks.forEach(task => {
        if (task.method && layoutGridFormPropertiesUtils[task.method]) {
            ret = layoutGridFormPropertiesUtils[task.method](obj, ...task.args)
        }
    });
    return ret;
}
